.

The R Language: Part 02

R Objetcs

Variable Assignment

A basic concept in (statistical) programming is called a variable.

A variable allows you to store a value (e.g. 4) or an object (e.g. a function description) in R. You can then later use this variable’s name to easily access the value or the object that is stored within this variable.

Save information as an R objetc with the greater than sign followed by a minus, e.g. an arrow: <-

#name of new objetc         assignment operator, "gets"         information to store in the objetc
foo                                 <-                            42

Common R Workflow

Save output of one function as an R objetc to use in a second function

foo
[1] 4
factorial(foo)
[1] 24

Remove objetcs from environment

You can remove an objetc with rm

fac_foo
[1] 24
rm(foo)
rm(fac_foo)

To consider…

  • Object names cannot beggin with numbers. Wise to avoid names already in use.
mean
[1] 0.1731301
pi
[1] 3.141593
  • R will treat the lowercase and capital letters as different.

Data Structures

You can save more than a single number in an objetc by creating a vector, matrix, or array.

class(WorldPhones)
[1] "matrix"

Vectors

  • Combine multiple elements into one dimensional array.

  • Create with the c function.

vec
[1]   1   2   3  10 100

Matrices

  • Combine multiple elements into a two dimensional array.

  • Create with the matrix function.

mat
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
mat
     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6
mat
     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]    1    2    3    4    5    6    1

Math: element- wise

vec; vec2
[1]   1   2   3  10 100
[1]   5   6   7  14 104
vec * 4 ; vec2 * 4
[1]   4   8  12  40 400
[1]  20  24  28  56 416
vec * vec ; vec2 * vec2; c(23,vec) * c(vec2,2);vec;vec2
[1]     1     4     9   100 10000
[1]    25    36    49   196 10816
[1]  115    6   14   42 1040  200
[1]   1   2   3  10 100
[1]   5   6   7  14 104

Matrix multiplication

inner

vec; vec %*% vec; mat;mat %*% mat
[1]   1   2   3  10 100
      [,1]
[1,] 10114
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
     [,1] [,2] [,3]
[1,]   30   66  102
[2,]   36   81  126
[3,]   42   96  150

outer

vec; vec %o% vec; mat; mat %o% mat; mat %o% vec
[1]   1   2   3  10 100
     [,1] [,2] [,3] [,4]  [,5]
[1,]    1    2    3   10   100
[2,]    2    4    6   20   200
[3,]    3    6    9   30   300
[4,]   10   20   30  100  1000
[5,]  100  200  300 1000 10000
     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6
, , 1, 1

     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6

, , 2, 1

     [,1] [,2]
[1,]    2    8
[2,]    4   10
[3,]    6   12

, , 3, 1

     [,1] [,2]
[1,]    3   12
[2,]    6   15
[3,]    9   18

, , 1, 2

     [,1] [,2]
[1,]    4   16
[2,]    8   20
[3,]   12   24

, , 2, 2

     [,1] [,2]
[1,]    5   20
[2,]   10   25
[3,]   15   30

, , 3, 2

     [,1] [,2]
[1,]    6   24
[2,]   12   30
[3,]   18   36

, , 1

     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6

, , 2

     [,1] [,2]
[1,]    2    8
[2,]    4   10
[3,]    6   12

, , 3

     [,1] [,2]
[1,]    3   12
[2,]    6   15
[3,]    9   18

, , 4

     [,1] [,2]
[1,]   10   40
[2,]   20   50
[3,]   30   60

, , 5

     [,1] [,2]
[1,]  100  400
[2,]  200  500
[3,]  300  600

transpose

mat
     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6
t(mat)
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6

Data types

R can recognize different types of data.

We’ll look at four basic types:

  • numbers
  • character strings (text)
  • logical
  • factor

numeric

  • Any number, no quotes.
  • Appropiate for math.
12+4
[1] 16
3000000
[1] 3e+06
class(0.000001)
[1] "numeric"

character

  • Any symbols surronded by quotes.
  • Appropiate for words, variable names, messages, any text.
print('hello')
[1] "hello"
class("hello")
[1] "character"
"12+4"
[1] "12+4"
class("12+4")
[1] "character"
"hello" + "world"
Error in "hello" + "world" : non-numeric argument to binary operator
nchar("hello")
[1] 5
paste("hello","world",sep=",");paste("hello","world",sep=" 2342eafdsghsIJGBJmdxfghvb ")
[1] "hello,world"
[1] "hello 2342eafdsghsIJGBJmdxfghvb world"
paste(paste("hello","world",sep=","),paste("como","estas",sep="_"),2,sep="::"); paste(paste("hello","world",sep=","),paste("como","estas",sep="_"),"2",sep="::"); paste("hola","sin","espacios",sep="");paste0("hola","sin","espacios")
[1] "hello,world::como_estas::2"
[1] "hello,world::como_estas::2"
[1] "holasinespacios"
[1] "holasinespacios"

To consider…

wich are numbers?

1; "1"; "one"
[1] 1
[1] "1"
[1] "one"
c(1, "1","one")
[1] "1"   "1"   "one"

logical

TRUE or FALSE - R’s form of binary data. - Useful for logical tests. - And Very Useful when whe want to filter datasets…

3<4
[1] TRUE
x <- c(1, 2, 3, 4, 5)
x
[1] 1 2 3 4 5
x > 3
[1] FALSE FALSE FALSE  TRUE  TRUE
x >= 3
[1] FALSE FALSE  TRUE  TRUE  TRUE
x < 3
[1]  TRUE  TRUE FALSE FALSE FALSE
x <= 3
[1]  TRUE  TRUE  TRUE FALSE FALSE
x == 3
[1] FALSE FALSE  TRUE FALSE FALSE
x != 3
[1]  TRUE  TRUE FALSE  TRUE  TRUE
x = 3
c(3,4,5,6) %in% c(2, 3, 4) 
[1]  TRUE  TRUE FALSE FALSE
unique(titanic2$age)
[1] adult child
Levels: adult child
titanic2%>%
  filter(fate!="survived" & 
           class%in%c("1st","3rd"))
class(TRUE)
[1] "logical"
class(T) ; class(F)
[1] "logical"
[1] "logical"
class(3<4)
[1] "logical"

factor

R’s form of categorical data. Saved as an integer with a set of labels (e.g. levels)

fac<-factor(c("a","b","c"))
fac
[1] a b c
Levels: a b c
class(fac)
[1] "factor"

One proof that factor makes sense

To consider…

  • Remember that if you want to assign a number or an object to a variable in R, you can make use of the assignment operator <-. Alternatively, you can use =, but <- is widely preferred in the R community.
# Add these two variables together
my_apples + my_oranges
[1] 11

watch out!

Be careful with the operations between different types/classes of objects

# Assign a value to the variable my_apples
my_apples <- 5 
# Fix the assignment of my_oranges
my_oranges <- "six" 
# Create the variable my_fruit and print it out
my_fruit <- my_apples + my_oranges
Error in my_apples + my_oranges : non-numeric argument to binary operator
class(my_oranges)
[1] "character"
class(my_oranges)
[1] "character"

So, in general, it’s a good idea to check that the objetcs that are opperating between each other, are of the same class/type or we have to be conscients that sometimes, if the types are not equals but they are “almost operables”, R will change at least one of them to a type that make both be “totaly operables”.

There could be some warnings about this… it could be a good idea to knoe a little more about the data types that will be jumping in at our work.

Saving differents types in one single object…

On a Vector…

vec<-c(1,"R","TRUE")
class(vec)
[1] "character"
vec
[1] "1"    "R"    "TRUE"

Sure a Matrix will do it…

matriz_de_Camilo<-matrix(cbind(c(1,2,3),
                         c("R","S","T"),
                         c(TRUE,FALSE,TRUE)),ncol=3)
class(matriz_de_Camilo)
[1] "matrix"
matriz_de_Camilo
     [,1] [,2] [,3]   
[1,] "1"  "R"  "TRUE" 
[2,] "2"  "S"  "FALSE"
[3,] "3"  "T"  "TRUE" 
for(row_tmp in 1:nrow(matriz_de_Camilo)){
  print(class(matriz_de_Camilo[row_tmp,]))
}
[1] "character"
[1] "character"
[1] "character"
for(col_tmp in 1:ncol(matriz_de_Camilo)){
  print(class(matriz_de_Camilo[,col_tmp]))
}
[1] "character"
[1] "character"
[1] "character"
matriz_de_Camilo
     [,1] [,2] [,3]   
[1,] "1"  "R"  "TRUE" 
[2,] "2"  "S"  "FALSE"
[3,] "3"  "T"  "TRUE" 

What the … is R doing?!

Always remember Coercion

Always remember Coercion

So, isn’t there any way we I can do it?

Really? ;(

There is a way… Thank God for the data frames

And for the lists

Data frames

When we read a .csv file and store it on a object, that will be a data.frame class

class(titanic2)
[1] "data.frame"

And now, just because it’s worthy…

  • There are some types of objects very similar to the data frames but that are not exactly one of those

  • They came from the package dplyr (one of my favorites) and its class is called tibble (nickname: data_frame) instead of data.frame

  • Example:

class(flights)
[1] "tbl_df"     "tbl"        "data.frame"
  • Print on console:

  • titanic2 &, afterwards
  • flights

  • Do you see any difference?

List

nlst
$one
[1] 1

$two
[1] 2

$many
[1] 1 2 3
nlst<-list("Eduardo"=df_de_Camilo,"Camilo"=matriz_de_Camilo,"Carlos"=c(T,FALSE,TRUE,F))
#Print directly on console
nlst
$Eduardo

$Camilo
     [,1] [,2] [,3]   
[1,] "1"  "R"  "TRUE" 
[2,] "2"  "S"  "FALSE"
[3,] "3"  "T"  "TRUE" 

$Carlos
[1]  TRUE FALSE  TRUE FALSE
nlst$Eduardo
#Print directly on console
nlst[1]
$Eduardo
NA
#Print directly on console
nlst[[1]]
nlst02<-list("Eduardo"=df_de_Camilo,"Camilo"=matriz_de_Camilo,"Carlos"=c(T,FALSE,TRUE,F),"unalistadentrodeunalista"=nlst)
#Print directly on console
nlst02
$Eduardo

$Camilo
     [,1] [,2] [,3]   
[1,] "1"  "R"  "TRUE" 
[2,] "2"  "S"  "FALSE"
[3,] "3"  "T"  "TRUE" 

$Carlos
[1]  TRUE FALSE  TRUE FALSE

$unalistadentrodeunalista
$unalistadentrodeunalista$Eduardo

$unalistadentrodeunalista$Camilo
     [,1] [,2] [,3]   
[1,] "1"  "R"  "TRUE" 
[2,] "2"  "S"  "FALSE"
[3,] "3"  "T"  "TRUE" 

$unalistadentrodeunalista$Carlos
[1]  TRUE FALSE  TRUE FALSE
LS0tCnRpdGxlOiAiIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIGRmX3ByaW50OiBwYWdlZAogIGh0bWxfZG9jdW1lbnQ6CiAgICBkZl9wcmludDogcGFnZWQKLS0tCgojIDxhPjxpbWcgc3JjPSd3d3cvYmJ2YV91YWR5MDIucG5nJyBhbGlnbj0icmlnaHQiIGhlaWdodD0iMTM5IiAvPjwvYT4KICAgLiA8YnIvPgoKI1RoZSBSIExhbmd1YWdlOiBQYXJ0IDAyCgojIyBSIE9iamV0Y3MKCiMjIyBWYXJpYWJsZSBBc3NpZ25tZW50CkEgYmFzaWMgY29uY2VwdCBpbiAoc3RhdGlzdGljYWwpIHByb2dyYW1taW5nIGlzIGNhbGxlZCBhICoqdmFyaWFibGUqKi4gCgpBIHZhcmlhYmxlIGFsbG93cyB5b3UgdG8gc3RvcmUgYSB2YWx1ZSAoZS5nLiA0KSBvciBhbiBvYmplY3QgKGUuZy4gYSBmdW5jdGlvbiBkZXNjcmlwdGlvbikgaW4gUi4gWW91IGNhbiB0aGVuIGxhdGVyIHVzZSB0aGlzIHZhcmlhYmxlJ3MgbmFtZSB0byBlYXNpbHkgYWNjZXNzIHRoZSB2YWx1ZSBvciB0aGUgb2JqZWN0IHRoYXQgaXMgc3RvcmVkIHdpdGhpbiB0aGlzIHZhcmlhYmxlLiAKClNhdmUgaW5mb3JtYXRpb24gYXMgYW4gUiBvYmpldGMgd2l0aCB0aGUgKmdyZWF0ZXIgdGhhbiogc2lnbiBmb2xsb3dlZCBieSAqYSBtaW51cyosIGUuZy4gYW4gYXJyb3c6IGA8LWAKYGBge3J9CiNuYW1lIG9mIG5ldyBvYmpldGMgICAgICAgICBhc3NpZ25tZW50IG9wZXJhdG9yLCAiZ2V0cyIgICAgICAgICBpbmZvcm1hdGlvbiB0byBzdG9yZSBpbiB0aGUgb2JqZXRjCmZvbyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwtICAgICAgICAgICAgICAgICAgICAgICAgICAgIDQyCmBgYAoKIyMjIENvbW1vbiBSIFdvcmtmbG93ClNhdmUgb3V0cHV0IG9mIG9uZSBmdW5jdGlvbiBhcyBhbiBSIG9iamV0YyB0byB1c2UgaW4gYSBzZWNvbmQgZnVuY3Rpb24KYGBge3J9CmZvbyA8LSByb3VuZCgzLjE0MTUpICsgMQpmb28KYGBgCgpgYGB7cn0KZmFjdG9yaWFsKGZvbykKYGBgCgojIyBSZW1vdmUgb2JqZXRjcyBmcm9tIGVudmlyb25tZW50CllvdSBjYW4gcmVtb3ZlIGFuIG9iamV0YyB3aXRoIGBybWAKYGBge3J9CmZhY19mb288LWZhY3RvcmlhbChmb28pCmZhY19mb28KYGBgCgpgYGB7cn0Kcm0oZm9vKQpybShmYWNfZm9vKQpgYGAKCiMjIyBUbyBjb25zaWRlci4uLgoKLSBPYmplY3QgbmFtZXMgY2Fubm90IGJlZ2dpbiB3aXRoIG51bWJlcnMuIFdpc2UgdG8gYXZvaWQgbmFtZXMgYWxyZWFkeSBpbiB1c2UuCgpgYGB7cn0KbWVhbjwtbWVhbihybm9ybSgxMDApKQptZWFuCj9tZWFuCmBgYApgYGB7cn0Kcm0obWVhbikKcGkKcGk8LTEKcGkKcm0ocGkpCnBpCmBgYAoKLSBSIHdpbGwgdHJlYXQgdGhlIGxvd2VyY2FzZSBhbmQgY2FwaXRhbCBsZXR0ZXJzIGFzIGRpZmZlcmVudC4KCgojIyBEYXRhIFN0cnVjdHVyZXMKCllvdSBjYW4gc2F2ZSBtb3JlIHRoYW4gYSBzaW5nbGUgbnVtYmVyIGluIGFuIG9iamV0YyBieSBjcmVhdGluZyBhICp2ZWN0b3IqLCAqbWF0cml4Kiwgb3IgKmFycmF5Ki4KCmBgYHtyfQpXb3JsZFBob25lcwpjbGFzcyhXb3JsZFBob25lcykKYGBgCgoKIyMjIFZlY3RvcnMKCi0gQ29tYmluZSBtdWx0aXBsZSBlbGVtZW50cyBpbnRvIG9uZSBkaW1lbnNpb25hbCBhcnJheS4KCi0gQ3JlYXRlIHdpdGggdGhlIGBjYCBmdW5jdGlvbi4KYGBge3J9CnZlYzwtYygxLDIsMywxMCwxMDApCnZlYwpgYGAKCiMjIyBNYXRyaWNlcwoKLSBDb21iaW5lIG11bHRpcGxlIGVsZW1lbnRzIGludG8gYSB0d28gZGltZW5zaW9uYWwgYXJyYXkuCgotIENyZWF0ZSB3aXRoIHRoZSBgbWF0cml4YCBmdW5jdGlvbi4KYGBge3J9CiAgICAgICAgICAgICN2ZWN0b3Igb2YgZWxlbWVudHMgdG8gZ28gaW4gdGhlIG1hdHJpeCAgICAgbnVtYmVyIG9mIHJvd3MgZm9yIG1hdHJpeAoKbWF0PC1tYXRyaXgoZGF0YSA9IGMoMSwyLDMsNCw1LDYpLCAgICAgICAgICAgICAgICAgICAgICBucm93ID0gMikKbWF0CmBgYAoKYGBge3J9CiAgICAgICAgICAgICN2ZWN0b3Igb2YgZWxlbWVudHMgdG8gZ28gaW4gdGhlIG1hdHJpeCAgICAgbnVtYmVyIG9mIHJvd3MgZm9yIG1hdHJpeAoKbWF0PC1tYXRyaXgoZGF0YSA9IGMoMSwyLDMsNCw1LDYpLCAgICAgICAgICAgICAgICAgICAgICBucm93ID0gMykKbWF0CmBgYAoKCmBgYHtyfQogICAgICAgICAgICAjdmVjdG9yIG9mIGVsZW1lbnRzIHRvIGdvIGluIHRoZSBtYXRyaXggICAgIG51bWJlciBvZiBjb2xzIGZvciBtYXRyaXgKI3JiaW5kKGMoMSwyLDMsNCw1LDYpLGMoMSwyLDMsNCw1LDYpKjIpCm1hdDwtbWF0cml4KGMoMSwyLDMsNCw1LDYpLG5jb2w9MikKbWF0CmBgYAoKIyMjIE1hdGg6IGVsZW1lbnQtIHdpc2UKYGBge3J9CnZlYzI8LXZlYwp2ZWMyPC12ZWMgKyA0CnZlYzsgdmVjMgpgYGAKCmBgYHtyfQp2ZWMgKiA0IDsgdmVjMiAqIDQKYGBgCgpgYGB7cn0KdmVjICogdmVjIDsgdmVjMiAqIHZlYzI7IGMoMjMsdmVjKSAqIGModmVjMiwyKTt2ZWM7dmVjMgpgYGAKCiMjIyBNYXRyaXggbXVsdGlwbGljYXRpb24KCioqaW5uZXIqKgpgYGB7cn0KbWF0PC1tYXRyaXgoYygxLDIsMyw0LDUsNiw3LDgsOSksbmNvbD0zKQp2ZWM7IHZlYyAlKiUgdmVjOyBtYXQ7bWF0ICUqJSBtYXQKYGBgCgoqKm91dGVyKioKYGBge3J9CgptYXQ8LW1hdHJpeChjKDEsMiwzLDQsNSw2KSxuY29sPTIpCnZlYzsgdmVjICVvJSB2ZWM7IG1hdDsgbWF0ICVvJSBtYXQ7IG1hdCAlbyUgdmVjCmBgYAoKKip0cmFuc3Bvc2UqKgpgYGB7cn0KbWF0CmBgYAoKYGBge3J9CnQobWF0KQpgYGAKCiMjRGF0YSB0eXBlcwpSIGNhbiByZWNvZ25pemUgZGlmZmVyZW50IHR5cGVzIG9mIGRhdGEuCgpXZSdsbCBsb29rIGF0IGZvdXIgYmFzaWMgdHlwZXM6CgotIG51bWJlcnMKLSBjaGFyYWN0ZXIgc3RyaW5ncyAodGV4dCkKLSBsb2dpY2FsCi0gZmFjdG9yCgoKIyMjIG51bWVyaWMKLSBBbnkgbnVtYmVyLCBubyBxdW90ZXMuIAotIEFwcHJvcGlhdGUgZm9yIG1hdGguCgpgYGB7cn0KMTIrNApgYGAKCmBgYHtyfQozMDAwMDAwCmBgYAoKYGBge3J9CmNsYXNzKDAuMDAwMDAxKQpgYGAKCiMjIyBjaGFyYWN0ZXIKCi0gQW55IHN5bWJvbHMgc3Vycm9uZGVkIGJ5IHF1b3Rlcy4KLSBBcHByb3BpYXRlIGZvciB3b3JkcywgdmFyaWFibGUgbmFtZXMsIG1lc3NhZ2VzLCBhbnkgdGV4dC4KCmBgYHtyfQpwcmludCgiaGVsbG8iKQpwcmludCgnaGVsbG8nKQoKICNwcmludCgiaGVsbG8nKSAjRVNUTyBFU1TDgSBNQUwKYGBgCgpgYGB7cn0KY2xhc3MoImhlbGxvIikKYGBgCgoKYGBge3J9CiIxMis0IgpgYGAKCmBgYHtyfQpjbGFzcygiMTIrNCIpCmBgYAoKYGBge3J9CiMiaGVsbG8iICsgIndvcmxkIgpgYGAKCmBgYHtyfQpuY2hhcigiaGVsbG8iKQpgYGAKCmBgYHtyfQpwYXN0ZSgiaGVsbG8iLCJ3b3JsZCIsc2VwPSIsIik7cGFzdGUoImhlbGxvIiwid29ybGQiLHNlcD0iIDIzNDJlYWZkc2doc0lKR0JKbWR4ZmdodmIgIikKYGBgCgoKYGBge3J9CnBhc3RlKCJoZWxsbyIsIndvcmxkIixzZXA9IiwiKTtwYXN0ZSgiY29tbyIsImVzdGFzIixzZXA9Il8iKTsKCnBhc3RlKHBhc3RlKCJoZWxsbyIsIndvcmxkIixzZXA9IiwiKSxwYXN0ZSgiY29tbyIsImVzdGFzIixzZXA9Il8iKSwyLHNlcD0iOjoiKTsgcGFzdGUocGFzdGUoImhlbGxvIiwid29ybGQiLHNlcD0iLCIpLHBhc3RlKCJjb21vIiwiZXN0YXMiLHNlcD0iXyIpLCIyIixzZXA9Ijo6Iik7IHBhc3RlKCJob2xhIiwic2luIiwiZXNwYWNpb3MiLHNlcD0iIik7cGFzdGUwKCJob2xhIiwic2luIiwiZXNwYWNpb3MiKQpgYGAKCiMjIyBUbyBjb25zaWRlci4uLgoqKndpY2ggYXJlIG51bWJlcnM/KioKCmBgYHtyfQoxOyAiMSI7ICJvbmUiCmBgYApgYGB7cn0KYygxLCAiMSIsIm9uZSIpCmBgYAojIyMgbG9naWNhbApgVFJVRWAgb3IgYEZBTFNFYAotIFIncyBmb3JtIG9mIGJpbmFyeSBkYXRhLiAKLSBVc2VmdWwgZm9yIGxvZ2ljYWwgdGVzdHMuCi0gQW5kIFZlcnkgVXNlZnVsIHdoZW4gd2hlIHdhbnQgdG8gZmlsdGVyIGRhdGFzZXRzLi4uCgpgYGB7cn0KMzw0CnggPC0gYygxLCAyLCAzLCA0LCA1KQp4CnggPiAzCnggPj0gMwp4IDwgMwp4IDw9IDMKeCA9PSAzCnggIT0gMwp4ID0gMwoKYygzLDQsNSw2KSAlaW4lIGMoMiwgMywgNCkgCgpgYGAKCmBgYHtyfQp0aXRhbmljMjwtcmVhZC5jc3YoImRhdGEvdGl0YW5pYzIuY3N2IixoZWFkZXIgPSBUKQp0aXRhbmljMgpgYGAKCmBgYHtyfQpsaWJyYXJ5KGRwbHlyKQp0aXRhbmljMiU+JQogIGZpbHRlcihhZ2U9PSJhZHVsdCIpCmBgYAoKYGBge3J9CnRpdGFuaWMyJT4lCiAgZmlsdGVyKGNsYXNzPT0iMXN0IikKYGBgCgpgYGB7cn0KdGl0YW5pYzIlPiUKICBmaWx0ZXIobWFsZTxtZWFuKG1hbGUpKQpgYGAKCmBgYHtyfQp0aXRhbmljMiU+JQogIGZpbHRlcihmZW1hbGU+PW1lYW4oZmVtYWxlKSkKYGBgCmBgYHtyfQp1bmlxdWUodGl0YW5pYzIkY2xhc3MpCnVuaXF1ZSh0aXRhbmljMiRhZ2UpCmBgYApgYGB7cn0KdGl0YW5pYzIlPiUKICBmaWx0ZXIoZmF0ZSE9InN1cnZpdmVkIiAmIAogICAgICAgICAgIGFzLm51bWVyaWMoY2xhc3MpPj0zICYgCiAgICAgICAgICAgYXMubnVtZXJpYyhhZ2UpPDIpCmBgYAoKYGBge3J9CnRpdGFuaWMyJT4lCiAgZmlsdGVyKGZhdGU9PSJzdXJ2aXZlZCIgJiAKICAgICAgICAgICBhcy5udW1lcmljKGNsYXNzKT49MyAmIAogICAgICAgICAgIGFzLm51bWVyaWMoYWdlKTwyKQpgYGAKCmBgYHtyfQp0aXRhbmljMiU+JQogIGZpbHRlcihmYXRlPT0ic3Vydml2ZWQiICYgCiAgICAgICAgICAgY2xhc3MlaW4lYygiMXN0IiwiM3JkIikpCmBgYAoKYGBge3J9CnRpdGFuaWMyJT4lCiAgZmlsdGVyKGZhdGUhPSJzdXJ2aXZlZCIgJiAKICAgICAgICAgICBjbGFzcyVpbiVjKCIxc3QiLCIzcmQiKSkKYGBgCgoKCmBgYHtyfQpjbGFzcyhUUlVFKQpgYGAKCmBgYHtyfQpjbGFzcyhUKSA7IGNsYXNzKEYpCmBgYAoKYGBge3J9CmNsYXNzKDM8NCkKYGBgCgojIyBmYWN0b3IKUidzIGZvcm0gb2YgY2F0ZWdvcmljYWwgZGF0YS4gU2F2ZWQgYXMgYW4gaW50ZWdlciB3aXRoIGEgc2V0IG9mIGxhYmVscyAoZS5nLiBsZXZlbHMpCmBgYHtyfQpmYWM8LWZhY3RvcihjKCJhIiwiYiIsImMiKSkKZmFjCmBgYApgYGB7cn0KY2xhc3MoZmFjKQpgYGAKKipPbmUgcHJvb2YgdGhhdCAqZmFjdG9yKiBtYWtlcyBzZW5zZSoqCmBgYHtyfQp0aXRhbmljMgpgYGAKCmBgYHtyfQpsaWJyYXJ5KGdncGxvdDIpCmdnPC1nZ3Bsb3QodGl0YW5pYzIsYWVzKHg9Y2xhc3MseT1hZ2UpKQpnZyArIGdlb21fcG9pbnQoYWVzKHNpemU9bWFsZSkpCmBgYApgYGB7cn0KZ2cgKyBnZW9tX3BvaW50KGFlcyhjb2xvcj1mYXRlKSkKYGBgCgpgYGB7cn0KZ2cwMTwtZ2cgKyBnZW9tX3BvaW50KGFlcyhjb2xvcj1mYXRlLHNpemU9bWFsZStmZW1hbGUpKQpnZzAxCmBgYApgYGB7cixmaWcuaGVpZ2h0PTYsZmlnLndpZHRoPTEwfQpsaWJyYXJ5KHBsb3RseSkKZ2dwbG90bHkoZ2cwMSkKYGBgCgoKCiMjIyBUbyBjb25zaWRlci4uLgoKLSBSZW1lbWJlciB0aGF0IGlmIHlvdSB3YW50IHRvIGFzc2lnbiBhIG51bWJlciBvciBhbiBvYmplY3QgdG8gYSB2YXJpYWJsZSBpbiBSLCB5b3UgY2FuIG1ha2UgdXNlIG9mIHRoZSBhc3NpZ25tZW50IG9wZXJhdG9yIGA8LWAuIEFsdGVybmF0aXZlbHksIHlvdSBjYW4gdXNlIGA9YCwgYnV0IGA8LWAgaXMgd2lkZWx5IHByZWZlcnJlZCBpbiB0aGUgUiBjb21tdW5pdHkuCgpgYGB7ciwgZWNobz1UUlVFfQojIEFzc2lnbiBhIHZhbHVlIHRvIHRoZSB2YXJpYWJsZXMgbXlfYXBwbGVzIGFuZCBteV9vcmFuZ2VzCm15X2FwcGxlcyAgPC0gNQpteV9vcmFuZ2VzIDwtIDYKCiMgQWRkIHRoZXNlIHR3byB2YXJpYWJsZXMgdG9nZXRoZXIKbXlfYXBwbGVzICsgbXlfb3JhbmdlcwoKIyBDcmVhdGUgdGhlIHZhcmlhYmxlIG15X2ZydWl0Cm15X2ZydWl0IDwtIG15X2FwcGxlcyArIG15X29yYW5nZXMKYGBgCgojIyB3YXRjaCBvdXQhCkJlIGNhcmVmdWwgd2l0aCB0aGUgb3BlcmF0aW9ucyBiZXR3ZWVuIGRpZmZlcmVudCB0eXBlcy9jbGFzc2VzIG9mIG9iamVjdHMKYGBge3IsIGVjaG89VFJVRX0KIyBBc3NpZ24gYSB2YWx1ZSB0byB0aGUgdmFyaWFibGUgbXlfYXBwbGVzCm15X2FwcGxlcyA8LSA1IAoKIyBGaXggdGhlIGFzc2lnbm1lbnQgb2YgbXlfb3JhbmdlcwpteV9vcmFuZ2VzIDwtICJzaXgiIApgYGAKCmBgYHtyLCBlY2hvPVRSVUV9CiMgQ3JlYXRlIHRoZSB2YXJpYWJsZSBteV9mcnVpdCBhbmQgcHJpbnQgaXQgb3V0CiMgbXlfZnJ1aXQgPC0gbXlfYXBwbGVzICsgbXlfb3JhbmdlcwpgYGAKCmBgYHtyLCBlY2hvPVRSVUV9CmNsYXNzKG15X29yYW5nZXMpCmBgYApgYGB7ciwgZWNobz1UUlVFfQpjbGFzcyhteV9vcmFuZ2VzKQpgYGAKU28sIGluIGdlbmVyYWwsIGl0J3MgYSBnb29kIGlkZWEgdG8gY2hlY2sgdGhhdCB0aGUgb2JqZXRjcyB0aGF0IGFyZSBvcHBlcmF0aW5nIGJldHdlZW4gZWFjaCBvdGhlciwgYXJlIG9mIHRoZSBzYW1lIGNsYXNzL3R5cGUgb3Igd2UgaGF2ZSB0byBiZSBjb25zY2llbnRzIHRoYXQgc29tZXRpbWVzLCBpZiB0aGUgdHlwZXMgYXJlIG5vdCBlcXVhbHMgYnV0IHRoZXkgYXJlICJhbG1vc3Qgb3BlcmFibGVzIiwgKlIqIHdpbGwgY2hhbmdlIGF0IGxlYXN0IG9uZSBvZiB0aGVtIHRvIGEgdHlwZSB0aGF0IG1ha2UgYm90aCBiZSAidG90YWx5IG9wZXJhYmxlcyIuIAoKVGhlcmUgY291bGQgYmUgc29tZSB3YXJuaW5ncyBhYm91dCB0aGlzLi4uIGl0IGNvdWxkIGJlIGEgZ29vZCBpZGVhIHRvIGtub2UgYSBsaXR0bGUgbW9yZSBhYm91dCB0aGUgKipkYXRhIHR5cGVzKiogdGhhdCB3aWxsIGJlIGp1bXBpbmcgaW4gYXQgb3VyIHdvcmsuCgojIyBTYXZpbmcgZGlmZmVyZW50cyB0eXBlcyBpbiBvbmUgc2luZ2xlIG9iamVjdC4uLgoKKk9uIGEgVmVjdG9yLi4uKgpgYGB7cn0KdmVjPC1jKDEsIlIiLCJUUlVFIikKYGBgCgpgYGB7cn0KY2xhc3ModmVjKQpgYGAKCmBgYHtyfQp2ZWMKYGBgCgoqU3VyZSBhIE1hdHJpeCB3aWxsIGRvIGl0Li4uKgpgYGB7cn0KbWF0cml6X2RlX0NhbWlsbzwtbWF0cml4KGNiaW5kKGMoMSwyLDMpLAogICAgICAgICAgICAgICAgICAgICAgICAgYygiUiIsIlMiLCJUIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBjKFRSVUUsRkFMU0UsVFJVRSkpLG5jb2w9MykKYGBgCgpgYGB7cn0KY2xhc3MobWF0cml6X2RlX0NhbWlsbykKYGBgCgpgYGB7cn0KbWF0cml6X2RlX0NhbWlsbwpgYGAKCmBgYHtyfQpmb3Iocm93X3RtcCBpbiAxOm5yb3cobWF0cml6X2RlX0NhbWlsbykpewogIHByaW50KGNsYXNzKG1hdHJpel9kZV9DYW1pbG9bcm93X3RtcCxdKSkKfQogIApgYGAKCmBgYHtyfQpmb3IoY29sX3RtcCBpbiAxOm5jb2wobWF0cml6X2RlX0NhbWlsbykpewogIHByaW50KGNsYXNzKG1hdHJpel9kZV9DYW1pbG9bLGNvbF90bXBdKSkKfQogIApgYGAKCmBgYHtyfQptYXRyaXpfZGVfQ2FtaWxvCmBgYAoKKldoYXQgdGhlIC4uLiBpcyBSIGRvaW5nPyEqCgohW0Fsd2F5cyByZW1lbWJlciBDb2VyY2lvbl0od3d3L2NvZXJjaW9uLnBuZykKCioqU28sIGlzbid0IHRoZXJlIGFueSB3YXkgd2UgSSBjYW4gIGRvIGl0PyoqCgohWyBdKHd3dy9odWxrX3BlbnNhdGl2ZS5qcGcpCgoKKipSZWFsbHk/IDsoICoqCgohWyBdKHd3dy9pcm9tYW5fcGVuc2F0aXZlLmpwZykKCgoqKlRoZXJlIGlzIGEgd2F5Li4uIFRoYW5rIEdvZCBmb3IgdGhlIGBkYXRhIGZyYW1lc2AuLi4qKgoKCgohWyBdKHd3dy9UaG9yX3llaWlpLmpwZykKCgoqKkFuZCBmb3IgdGhlIGBsaXN0c2AuLi4qKgoKIVsgXSh3d3cveWVlZWFhYWhoaC1sb2tpLmdpZikKCgojIyBEYXRhIGZyYW1lcwpgYGB7cn0KZGY8LWRhdGEuZnJhbWUoYygxLDIsMyksCiAgICAgICAgICAgICAgIGMoIlIiLCJTIiwiVCIpLAogICAgICAgICAgICAgICBjKFRSVUUsRkFMU0UsVFJVRSkpCmRmCmBgYAoKYGBge3J9CmRmX2RlX0NhbWlsbzwtYXMuZGF0YS5mcmFtZShtYXRyaXpfZGVfQ2FtaWxvKQpkZl9kZV9DYW1pbG8KYGBgCmBgYHtyfQphcy5kYXRhLmZyYW1lKG1hdHJpel9kZV9DYW1pbG8sc3RyaW5nc0FzRmFjdG9ycyA9IEYpCmBgYAoKKipXaGVuIHdlIHJlYWQgYSAqLmNzdiogZmlsZSBhbmQgc3RvcmUgaXQgb24gYSBvYmplY3QsIHRoYXQgd2lsbCBiZSBhIGBkYXRhLmZyYW1lYCBjbGFzcyoqCgpgYGB7cn0KdGl0YW5pYzIgIyMgcmVtZW1iZXIgaG93IHdlIGdvdCB0aGlzIG9iamVjdDogcmVhZC5jc3YoImRhdGEvdGl0YW5pYzIuY3N2IixoZWFkZXIgPSBUKQpjbGFzcyh0aXRhbmljMikKYGBgCgoqKkFuZCBub3csIGp1c3QgYmVjYXVzZSBpdCdzIHdvcnRoeS4uLioqCgohWyBdKHd3dy9waWV0cmFkYXRhLnBuZykKCi0gVGhlcmUgYXJlIHNvbWUgdHlwZXMgb2Ygb2JqZWN0cyB2ZXJ5IHNpbWlsYXIgdG8gdGhlIGBkYXRhIGZyYW1lc2AgYnV0IHRoYXQgYXJlIG5vdCBleGFjdGx5IG9uZSBvZiB0aG9zZQoKLSBUaGV5IGNhbWUgZnJvbSB0aGUgcGFja2FnZSBgZHBseXJgICoob25lIG9mIG15IGZhdm9yaXRlcykqIGFuZCBpdHMgY2xhc3MgaXMgY2FsbGVkIGB0aWJibGVgICoobmlja25hbWU6ICoqYGRhdGFfZnJhbWVgKiopKiBpbnN0ZWFkIG9mICoqYGRhdGEuZnJhbWVgKioKCi0gRXhhbXBsZToKYGBge3J9CmxpYnJhcnkobnljZmxpZ2h0czEzKQpmbGlnaHRzCmBgYAoKYGBge3J9CmNsYXNzKGZsaWdodHMpCmBgYAoKLSBQcmludCBvbiBjb25zb2xlOgoKICAtIGB0aXRhbmljMmAKICAmLCBhZnRlcndhcmRzCiAgLSBgZmxpZ2h0c2AKICAKLSBEbyB5b3Ugc2VlIGFueSBkaWZmZXJlbmNlPwoKIyMgTGlzdAoKIVsgXSh3d3cvVGhlYmFybmV5YmFnMDEuanBnKQoKIVsgXSh3d3cvVGhlYmFybmV5YmFnMDIuanBnKQpgYGB7cn0KbmxzdDwtbGlzdChvbmU9MSx0d289MixtYW55PWMoMSwyLDMpKQpubHN0CmBgYApgYGB7cn0KbmxzdDwtbGlzdCgiRWR1YXJkbyI9ZGZfZGVfQ2FtaWxvLCJDYW1pbG8iPW1hdHJpel9kZV9DYW1pbG8sIkNhcmxvcyI9YyhULEZBTFNFLFRSVUUsRikpCiNQcmludCBkaXJlY3RseSBvbiBjb25zb2xlCm5sc3QKYGBgCmBgYHtyfQpubHN0JEVkdWFyZG8KYGBgCgpgYGB7cn0KI1ByaW50IGRpcmVjdGx5IG9uIGNvbnNvbGUKbmxzdFsxXQpgYGAKCmBgYHtyfQojUHJpbnQgZGlyZWN0bHkgb24gY29uc29sZQpubHN0W1sxXV0KYGBgCgpgYGB7cn0KbmxzdDAyPC1saXN0KCJFZHVhcmRvIj1kZl9kZV9DYW1pbG8sIkNhbWlsbyI9bWF0cml6X2RlX0NhbWlsbywiQ2FybG9zIj1jKFQsRkFMU0UsVFJVRSxGKSwidW5hbGlzdGFkZW50cm9kZXVuYWxpc3RhIj1ubHN0KQojUHJpbnQgZGlyZWN0bHkgb24gY29uc29sZQpubHN0MDIKYGBgCgpgYGB7cn0KCmBgYAoK